#pragma once
/*
 *      Copyright (C) 2005-2011 Team XBMC
 *      http://www.xbmc.org
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with XBMC; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#include "platform/util/StdString.h"
#include "platform/sockets/tcp.h"
#include "platform/util/util.h"
#include "platform/util/buffer.h"
#include "lib/protocol.h"
#include "lib/device.h"

using namespace std;

#define 	ETP_INVALID_TIME 	0xFFFFFFFFFFFFFFFF
#define 	ETP_LIVE_POS	 	0xFFFFFFFFFFFFFFFF


class PVREtpSocket : public PLATFORM::CTcpSocket
{
	public :
		PVREtpSocket(const CStdString &, uint16_t);
		~PVREtpSocket(void);

		ssize_t							Get8(uint8_t *);
		ssize_t							Get16(uint8_t *);
		ssize_t							Get32(uint8_t *);
		ssize_t							Get64(uint8_t *);

		ssize_t							Send8(uint8_t *);
		ssize_t							Send16(uint8_t *);
		ssize_t							Send32(uint8_t *);
		ssize_t							Send64(uint8_t *);

		bool							SendProtocolCMD(PROTOCOL_CMD_STRUCT *);
		void 							SetOpenTimeout(uint64_t t) {m_OpenTimeout = t;};
		void 							SetRWTimeout(uint64_t t) {m_RWTimeout = t;};
		void							Flush(void);

	private :
		uint64_t						m_OpenTimeout;
		uint64_t						m_RWTimeout;

		ssize_t							SendDataSize(uint8_t *, int);
		ssize_t							GetDataSize(uint8_t *, int);
		bool			 				Connect(void);
};

class PVREtpProtocol
{
	public:
		PVREtpProtocol(CStdString, uint16_t);
		~PVREtpProtocol(void);

		bool 							SendKeepAlive(void);
		bool							Ping(void);
		int								Status(void);


		bool 							TuneGetCtrlPort(void);
		bool							TuneStream(uint32_t);
		bool							TuneRecording(uint32_t);
		bool							IsStreaming(void);

		bool							CloseStream(void);
		ssize_t							ReadBytesFromStream(uint8_t *, uint32_t);
		bool							WriteToData(uint8_t *, uint32_t);
		uint64_t						StreamSetTimePos(uint64_t);
		bool 							StreamSetTimePosDone(bool);

		uint64_t						StreamGetTimePos(void);
		uint64_t						StreamGetTimeEnd(void);
		uint64_t						StreamGetTimeStart(void);

		uint64_t						GetEPG(char *);
		bool							GetEPGNext(TIMER_STRUCT_SEND*, TIMER_STRUCT_EXTRA *);
		void							GetEPGDone(void);


		void							GetStartPos(int);
		void							GetCurrentPos(int);
		void							GetEndPos(int);
		void							SeekByPos(int);


		bool							GetStreamInfo(void);
		bool							GetStreamInfoNext(TUNER_STREAM_STRUCT *);
		void							GetStreamInfoDone(void);

		void							GetStartTime(int);
		void							GetCurrentTime(int);
		void							GetEndTime(int);
		void							SeekByTime(int);

		int								GetChannelCount(void);
		bool							GetChannelList(void);
		bool					 		GetChannelListNext(PROTOCOL_CHANNEL_STRUCT*);
		void							GetChannelListDone(void);


		uint64_t						GetRecordingSeqNum(void);
		int								GetRecordingCount(void);
		uint32_t						GetRecordingList(void);
		bool					 		GetRecordingListNext(TIMER_STRUCT_SEND*);
		void							GetRecordingListDone(void);
		bool							DeleteRecording(uint32_t);

		uint64_t						GetTimerSeqNum(void);
		int								GetTimerCount(void);
		uint32_t						GetTimerList(void);
		bool							GetTimerListNext(TIMER_STRUCT_SEND*);
		void							GetTimerListDone(void);
		bool							DeleteTimer(uint32_t);

		bool							AddTimer(TIMER_STRUCT_SEND*);
		bool							UpdateTimer(TIMER_STRUCT_SEND*);

		bool 							OpenLive(void);
		bool 							OpenRecording(void);
		void							Flush(void);


	private:
		PLATFORM::CMutex				m_mutex;
//		PLATFORM::CLockObject 			m_mutex;

		PVREtpSocket			 		*m_TcpMain;
		PVREtpSocket			 		*m_TcpRec;
		PVREtpSocket			 		*m_TcpTimers;
		PVREtpSocket			 		*m_TcpEPG;
		PVREtpSocket			 		*m_TcpChan;
		PVREtpSocket 					*m_TcpData;
//		PVREtpSocket 					*m_TcpInfo;

		CStdString						m_strRemoteIP;
		int								m_iRemoteMainPort;
		int								m_iRemoteDataPort;
		bool							CloseMain(void);
		uint8_t 						Get8NoStream(uint8_t);
		uint16_t 						Get16NoStream(uint8_t);
		uint32_t 						Get32NoStream(uint8_t);
		uint64_t 						Get64NoStream(uint8_t);

		uint8_t 						Get8Stream(uint8_t);
		uint16_t 						Get16Stream(uint8_t);
		uint32_t 						Get32Stream(uint8_t);
		uint64_t 						Get64Stream(uint8_t);

		bool							GetStreamResp(uint8_t, uint8_t *, int);
		bool 							GetNoStreamResp(uint8_t, uint8_t *, int);
		bool							DeleteTimerRecording(uint8_t, uint32_t);
};

